package com.jiayou

import com.jiayou.emnu.FrameType
import com.jiayou.emnu.State
import com.jiayou.emnu.User
import kotlinx.coroutines.sync.Mutex
import java.io.Serializable
import java.util.*
import kotlin.collections.ArrayList

/**
@author lishuang
@data   2021-04-22  23:11
@info   协议 + 帧包
 */

/** ktor域 */
val ktor: MutableList<Map<User, Any>> = Collections.synchronizedList(ArrayList())
val ktorLock = Mutex()

/**
 * 协议包
 * T -> 实际数据类型
 */
interface Protocol<T : Serializable, T1 : Serializable, T2 : Serializable> : Serializable {
    fun getFrameType(): FrameType   //帧类型
    fun getSendTime(): Long          //发送时间
    fun getFrame(): Frame<T, T1, T2>?       //数据包
}

class TargetUser<U> : ArrayList<U>, Serializable {
    constructor(size: Int) : super(size)
    constructor(collection: Collection<U>) : super(collection)
}

/**
 * 默认协议包（字符串）
 * T -> 实际数据类型
 */
data class DefaultProtocolImpl<T : Serializable, T1 : Serializable, T2 : Serializable>(
    val type: FrameType,
    val data: Frame<T, T1, T2>? = null,
    val time: Long = System.currentTimeMillis()
) : Protocol<T, T1, T2> {
    override fun getFrameType() = type
    override fun getSendTime() = time
    override fun getFrame() = data
}

/**
 * 帧包
 * T -> 实际数据类型
 */
interface Frame<T : Serializable, T1 : Serializable, T2 : Serializable> : Serializable

/**
 * 权限验证包抽象
 * T -> 验证信息实际
 */
interface AuthenticatePackage<T : Serializable, T1 : Serializable, T2 : Serializable> : Frame<T, T1, T2> {
    fun username(): T1
    fun password(): T2
}

/**
 * 简单的权限验证包实现
 */
data class SimpleAuthPackPackageImpl(private val principals: String, private val evidence: String) :
    AuthenticatePackage<String, String, String> {
    override fun username() = principals
    override fun password() = evidence
}


/**
 * 字节数组权限验证包实现
 */
data class ByteAuthPackPackageImpl(private val principals: String, private val evidence: String) :
    AuthenticatePackage<ByteArray, String, String> {
    override fun username() = principals
    override fun password() = evidence
}

/**
 * 状态包
 */
data class StatePackage(
    private val username: String,
    private val state: State,
) : Frame<String, String, State>

/**
 * 数据包抽象
 * T -> 实际数据类型
 * E -> 目标接受对象
 */
interface DataPackage<T : Serializable, E1 : Serializable, E2 : Serializable> : Frame<T, E1, E2> {
    fun from(): E1
    fun to(): E2
    fun data(): T
}

/**
 * 简单的数据包实现（一对一通信）
 */
data class SimpleDataPackageImpl(
    private val from: String,
    private val to: String,
    private val data: String,
) : DataPackage<String, String, String> {
    override fun from() = from
    override fun to() = to
    override fun data() = data
}

/**
 * 简单的数据包实现（一对多通信）
 */
data class SimpleDataMultiplePackageImpl<T>(
    private val from: String,
    private val to: TargetUser<T>,
    private val data: String,
) : DataPackage<String, String, TargetUser<T>> {
    override fun from() = from
    override fun to() = to
    override fun data() = data
}

//单体消息（服务端用）
interface SinglePackage<T : Serializable, E : Serializable> : Frame<T, E, E> {
    val data: T
    val to: E
}

data class SimpleSinglePackageImpl(
    override val to: String,
    override val data: String,
) : SinglePackage<String, String>


//广播消息
interface BroadcastPackage<T : Serializable, T1 : Serializable, T2 : Serializable> : Frame<T, T1, T2> {
    val data: T
}

data class SimpleBroadcastPackageImpl(
    override val data: String
) : BroadcastPackage<String, String, String>


data class ByteBroadcastPackageImpl(
    override val data: ByteArray
) : BroadcastPackage<ByteArray, String, String> {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as ByteBroadcastPackageImpl

        if (!data.contentEquals(other.data)) return false
        return true
    }

    override fun hashCode(): Int {
        return data.contentHashCode()
    }
}